#include "mq_demo.h"
#include <iomanip>
#include <sstream>
#include <iostream>

MQDemo::MQDemo(const std::string &name_server, const std::string &topic,
               int send_interval_ms)
    : name_server_(name_server),
      topic_(topic),
      send_interval_ms_(send_interval_ms),
      running_(false),
      producer_(nullptr),
      mq_initialized_(false),
      gen_(rd_()),
      class_dist_(0, 3), // 0:car, 1:bus, 2:person, 3:bicycle
      coord_dist_(0, 1920),
      size_dist_(100, 500)
{

    // 初始化RocketMQ
    if (!initRocketMQ())
    {
        std::cerr << "Failed to initialize RocketMQ producer!" << std::endl;
    }
}

MQDemo::~MQDemo()
{
    stop();
    cleanupRocketMQ();
}

bool MQDemo::initRocketMQ()
{
    try
    {
        // 创建生产者实例
        producer_ = CreateProducer("DemoProducerGroup");
        if (!producer_)
        {
            std::cerr << "Failed to create RocketMQ producer!" << std::endl;
            return false;
        }

        // 设置NameServer地址
        if (SetProducerNameServerAddress(producer_, name_server_.c_str()) != OK)
        {
            std::cerr << "Failed to set NameServer address: " << name_server_ << std::endl;
            return false;
        }

        // 设置生产者属性
        SetProducerSendMsgTimeout(producer_, 3000);        // 3秒超时
        SetProducerMaxMessageSize(producer_, 1024 * 1024); // 1MB最大消息大小

        // 启动生产者
        if (StartProducer(producer_) != OK)
        {
            std::cerr << "Failed to start RocketMQ producer!" << std::endl;
            return false;
        }

        std::cout << "RocketMQ producer initialized successfully." << std::endl;
        std::cout << "NameServer: " << name_server_ << std::endl;
        std::cout << "Topic: " << topic_ << std::endl;

        mq_initialized_ = true;
        return true;
    }
    catch (const std::exception &e)
    {
        std::cerr << "Exception during RocketMQ initialization: " << e.what() << std::endl;
        return false;
    }
}

void MQDemo::cleanupRocketMQ()
{
    if (producer_)
    {
        if (mq_initialized_)
        {
            // 优雅关闭生产者
            ShutdownProducer(producer_);
            std::cout << "RocketMQ producer shutdown." << std::endl;
        }
        DestroyProducer(producer_);
        producer_ = nullptr;
        mq_initialized_ = false;
    }
}

bool MQDemo::sendRocketMQMessage(const json &msg)
{
    if (!mq_initialized_ || !producer_)
    {
        std::cerr << "RocketMQ producer not initialized!" << std::endl;
        return false;
    }

    try
    {
        // 将JSON转换为字符串
        std::string message_body = msg.dump();

        // 创建消息
        CMessage *rocketmq_msg = CreateMessage(topic_.c_str());
        if (!rocketmq_msg)
        {
            std::cerr << "Failed to create RocketMQ message!" << std::endl;
            return false;
        }

        // 设置消息体
        if (SetMessageBody(rocketmq_msg, message_body.c_str()) != OK)
        {
            std::cerr << "Failed to set message body!" << std::endl;
            DestroyMessage(rocketmq_msg);
            return false;
        }

        // 设置消息Key（使用identifyID作为去重key）
        std::string msg_key = msg["identifyID"];
        SetMessageKeys(rocketmq_msg, msg_key.c_str());

        // 设置消息属性（可选）
        SetMessageProperty(rocketmq_msg, "MSG_TYPE", "AI_DETECTION");
        SetMessageProperty(rocketmq_msg, "DEVICE_ID", msg["deviceID"].get<std::string>().c_str());
        SetMessageProperty(rocketmq_msg, "OBJ_TYPE", msg["objType"].get<std::string>().c_str());
        long long ttl_ms = 1 * 60 * 1000; // 1分钟换算为毫秒
        SetMessageProperty(rocketmq_msg, "TTL", std::to_string(ttl_ms).c_str());
        // 发送消息
        CSendResult send_result;
        if (SendMessageSync(producer_, rocketmq_msg, &send_result) != OK)
        {
            std::cerr << "Failed to send message!" << std::endl;
            DestroyMessage(rocketmq_msg);
            return false;
        }

        // 检查发送结果
        bool success = (send_result.sendStatus == E_SEND_OK);
        if (success)
        {
            std::cout << "Message sent successfully. MsgId: "
                      << send_result.msgId << std::endl;
        }
        else
        {
            std::cerr << "Message send failed. Status: "
                      << send_result.sendStatus << std::endl;
        }

        // 清理消息
        DestroyMessage(rocketmq_msg);
        return success;
    }
    catch (const std::exception &e)
    {
        std::cerr << "Exception during message sending: " << e.what() << std::endl;
        return false;
    }
}

void MQDemo::start()
{
    if (running_)
        return;

    if (!mq_initialized_)
    {
        std::cerr << "Cannot start: RocketMQ not initialized!" << std::endl;
        return;
    }

    running_ = true;
    send_thread_ = std::thread(&MQDemo::sendLoop, this);

    std::cout << "MQ Demo started. Sending messages every "
              << send_interval_ms_ << "ms" << std::endl;
}

void MQDemo::stop()
{
    running_ = false;
    if (send_thread_.joinable())
    {
        send_thread_.join();
    }
    std::cout << "MQ Demo stopped." << std::endl;
}

void MQDemo::sendLoop()
{
    int message_count = 0;
    int success_count = 0;

    while (running_)
    {
        try
        {
            // 生成随机数据
            json msg;
            generateRandomData(msg);

            // 发送消息 - 直接调用sendRocketMQMessage获取返回值
            bool send_success = sendRocketMQMessage(msg);

            message_count++;
            if (send_success)
            {
                success_count++;
            }

            std::cout << "[" << message_count << "] Send "
                      << (send_success ? "SUCCESS" : "FAILED")
                      << " - Success rate: "
                      << (message_count > 0 ? (success_count * 100 / message_count) : 0) << "%" << std::endl;

            if (message_count % 10 == 0)
            {
                std::cout << "=== Statistics: " << success_count << "/"
                          << message_count << " messages sent successfully ===" << std::endl;
            }

            // 打印消息内容（可选，调试用）
            if (message_count <= 3)
            { // 只打印前3条消息内容
                std::cout << "Message content: " << msg.dump(2) << std::endl;
            }
        }
        catch (const std::exception &e)
        {
            std::cerr << "Error in send loop: " << e.what() << std::endl;
        }

        // 等待指定间隔
        std::this_thread::sleep_for(std::chrono::milliseconds(send_interval_ms_));
    }

    std::cout << "Send loop finished. Total: " << message_count
              << " messages, Success: " << success_count << std::endl;
}

json MQDemo::buildMQMessage(const std::string &class_name,
                            const std::string &stream_id,
                            const std::string &small_uuid,
                            const std::string &small_img_path,
                            const std::string &large_img_path,
                            const cv::Rect &crop_box,
                            const cv::Size &orig_size,
                            time_t timestamp)
{
    std::string obj_type;
    if (class_name == "car" || class_name == "bus")
    {
        obj_type = "vehicle";
    }
    else
    {
        obj_type = class_name;
    }

    json msg;
    msg["objType"] = obj_type;
    msg["deviceID"] = stream_id;
    msg["locationMarkTime"] = timestamp;
    msg["identifyID"] = small_uuid;

    // 路径转换（简化版）
    msg["cropImage"] = replaceBasePath(small_img_path,
                                       config_.path.imgBasePath,
                                       config_.path.baseurl,
                                       config_.path.removePath);
    msg["origImage"] = replaceBasePath(large_img_path,
                                       config_.path.bigImgPath,
                                       config_.path.baseurl,
                                       config_.path.removePath);

    // 抠图坐标信息
    json crop_box_json;
    crop_box_json["x"] = crop_box.x;
    crop_box_json["y"] = crop_box.y;
    crop_box_json["width"] = crop_box.width;
    crop_box_json["height"] = crop_box.height;
    msg["cropBox"] = crop_box_json;

    // 原始图片尺寸信息
    json orig_size_json;
    orig_size_json["width"] = orig_size.width;
    orig_size_json["height"] = orig_size.height;
    msg["origSize"] = orig_size_json;

    return msg;
}

std::string MQDemo::replaceBasePath(const std::string &original_path,
                                    const std::string &base_path,
                                    const std::string &base_url,
                                    const std::string &remove_path)
{
    // 简化实现：直接返回模拟URL
    if (original_path.find(remove_path) == 0)
    {
        std::string relative_path = original_path.substr(remove_path.length());
        if (!relative_path.empty() && relative_path[0] == '/')
        {
            relative_path = relative_path.substr(1);
        }
        return base_url + "/" + relative_path;
    }
    return original_path;
}

// 修改sendMessage函数，使其返回bool值
bool MQDemo::sendMessage(const json &msg)
{
    // 使用RocketMQ发送消息
    return sendRocketMQMessage(msg);
}

void MQDemo::generateRandomData(json &msg)
{
    // 随机生成类别
    static const std::vector<std::string> classes = {"car", "bus", "person", "bicycle"};
    std::string class_name = classes[class_dist_(gen_)];

    // 随机生成流ID
    std::string stream_id = "camera_" + std::to_string(gen_() % 10 + 1);

    // 生成UUID
    std::stringstream uuid_ss;
    uuid_ss << std::hex << std::setfill('0');
    for (int i = 0; i < 16; ++i)
    {
        uuid_ss << std::setw(2) << (gen_() & 0xFF);
        if (i == 3 || i == 5 || i == 7 || i == 9)
        {
            uuid_ss << "-";
        }
    }
    std::string small_uuid = uuid_ss.str();

    // 生成时间戳
    time_t timestamp = std::chrono::system_clock::to_time_t(
        std::chrono::system_clock::now());

    // 生成路径
    std::string small_img_path = config_.path.imgBasePath + "/small/" +
                                 std::to_string(timestamp) + "_" + small_uuid + ".jpg";
    std::string large_img_path = config_.path.bigImgPath + "/large/" +
                                 std::to_string(timestamp) + "_" + small_uuid + ".jpg";

    // 生成随机坐标和尺寸
    int x = coord_dist_(gen_) % 1500;
    int y = coord_dist_(gen_) % 1000;
    int width = size_dist_(gen_);
    int height = size_dist_(gen_);

    // 确保不超出边界
    if (x + width > 1920)
        width = 1920 - x;
    if (y + height > 1080)
        height = 1080 - y;
    if (width < 10)
        width = 10; // 最小宽度
    if (height < 10)
        height = 10; // 最小高度

    cv::Rect crop_box(x, y, width, height);
    cv::Size orig_size(1920, 1080);

    // 构建消息
    msg = buildMQMessage(class_name, stream_id, small_uuid,
                         small_img_path, large_img_path,
                         crop_box, orig_size, timestamp);
}